
#ifndef __SANCAB_BIN_INDEX_HPP_2010__
#define __SANCAB_BIN_INDEX_HPP_2010__

#include <string>

#include <db_cxx.h>

#include "bocat/common/lrucache.hpp"

#include "recloc.hpp"
#include "record.hpp"
#include "indexiter.hpp"


namespace   sancab   {

class   BinIndex
{

	typedef	Db *	dbp_type;
	typedef	bocat::common::LRUCache< std::string, dbp_type >	dbp_cache_type;

public	:
	BinIndex( const std::string db_file, DbEnv* dbenv_p, u_int32_t n_tables = 64 );
	~BinIndex();

public  :
    int put( const std::string& kpin,
             const std::string& skey,
             const std::string& key,
             const RecordLocation&  loc );

    int get( const std::string& kpin,
             const std::string& skey,
             const std::string& key,
                RecordLocation& loc );

    int erase( const std::string& kpin,
               const std::string& skey,
               const std::string& key );

	int	erase( IndexIterator& it );

public	:
	int	slim( IndexIterator& it, int fileno );

public	:
	int	put( std::vector< Record >& record_v );
	int	get( std::vector< Record >& record_v );

private	:
	std::string	_db_file;
	DbEnv*		_dbenv_p;
	u_int32_t	_btree_minkey;

private	:
    const std::string   getTableName( const std::string& kpin, const std::string& key );

	u_int32_t		getPinId( const std::string& kpin );
	std::string		getTableName( u_int32_t pin );
	u_int32_t		getTableId( u_int32_t pin );

private	:

	u_int32_t		_n_tables;

	dbp_cache_type	_dbp_cache;
	boost::mutex	_dbp_cache_mutex;

	dbp_type	openTable( const std::string& table_name );
	void		closeAllTables();

	dbp_type	getDbp();

private	:
	#define	TABLE_HASH_UNKNOWN				0
	#define	TABLE_HASH_REVERSED_SITE_NAME	1

	int		_table_hash_strategy;

};  //// class BinIndex


}   //// namespace sancab


#endif  //// __SANCAB_BIN_INDEX_HPP_2010__


